package back_0417;

import busuanzi.util.MIMEs;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.DefaultFileRegion;
import io.netty.handler.codec.http.*;
import io.netty.handler.stream.ChunkedStream;

import javax.activation.MimetypesFileTypeMap;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import static io.netty.handler.codec.http.HttpHeaderUtil.isKeepAlive;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;

/**
 * Created by bruce on 15/4/4.
 */
public class StaticResourceHanlder2 {
    private static String staticFileFolder;
    private static String externalStaticFileFolder;

    public static void staticFileFolder(String staticFileFolder) {
        StaticResourceHanlder2.staticFileFolder = staticFileFolder;
    }

    public static void externalStaticFileFolder(String externalStaticFileFolder) {
        StaticResourceHanlder2.externalStaticFileFolder = externalStaticFileFolder;
    }

    public static void handle2(ChannelHandlerContext ctx, HttpRequest request) {
        try {

            final String uri = request.uri();
            final QueryStringDecoder query = new QueryStringDecoder(uri);

            String path = query.path();

            String fileName = path.substring(path.lastIndexOf('/') + 1);

            String mimeType = MIMEs.mimeTypeByPath(path);

            HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
            response.headers().set("Transfer-Encoding", "chunked");
            response.headers().set("content-type", mimeType);

//            if (isKeepAlive(request)) response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);


            ctx.write(response);

            InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
            if (in == null) in = Thread.currentThread().getContextClassLoader().getResourceAsStream(path.substring(1));

            ChannelFuture writeFuture = ctx.write(new ChunkedStream(in), ctx.newProgressivePromise());

            ChannelFuture lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);

            /*if (!isKeepAlive(request))*/
            lastContentFuture.addListener(ChannelFutureListener.CLOSE);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static boolean handle(ChannelHandlerContext ctx, HttpRequest request) {
        try {
            final String uri = request.uri();
            final QueryStringDecoder query = new QueryStringDecoder(uri);

            String path = query.path();

            String fileName = path.substring(path.lastIndexOf('/') + 1);

            String mimeType = MIMEs.mimeTypeByPath(path);

            HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
            response.headers().set("Transfer-Encoding", "chunked");
            response.headers().set(HttpHeaderNames.CONTENT_TYPE, mimeType);

            if (isKeepAlive(request)) response.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);

            ctx.write(response);

            InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
            if (in == null) in = Thread.currentThread().getContextClassLoader().getResourceAsStream(path.substring(1));

            System.out.println(in.available());
//            response.headers().setLong(HttpHeaderNames.CONTENT_LENGTH, in.available());

            ChunkedStream msg = new ChunkedStream(in);
            ChannelFuture writeFuture = ctx.write(msg, ctx.newProgressivePromise());

            ChannelFuture lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);

            if (!isKeepAlive(request)) lastContentFuture.addListener(ChannelFutureListener.CLOSE);
            msg.close();
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

        return true;
    }

    public static boolean handleResource(ChannelHandlerContext ctx, HttpRequest request) {
        try {
            final String uri = request.uri();
            final QueryStringDecoder query = new QueryStringDecoder(uri);

            String path = query.path();

//            String fileName = path.substring(path.lastIndexOf('/') + 1);

            String mimeType = MIMEs.getContentType(path);

            HttpResponse resourceResponse = new DefaultHttpResponse(HTTP_1_1, OK);

            resourceResponse.headers().set(HttpHeaderNames.CONTENT_TYPE, mimeType);

            if (isKeepAlive(request))
                resourceResponse.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);

//            Thread.currentThread().getContextClassLoader()


            boolean handled = false;

            if (!handled && staticFileFolder != null) {
                InputStream inputStream = null;

                ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
                String filePath = staticFileFolder + path.substring(1);

                URL url = classLoader.getResource(filePath);

                //考虑安全性 不允许显示目录内容

                if ("jar".equals(url.getProtocol())) {
                    URLConnection urlConnection = url.openConnection();
                    JarURLConnection jarUrlConnection = (JarURLConnection) urlConnection;
                    JarEntry jarEntry = jarUrlConnection.getJarEntry();
                    JarFile jarFile = jarUrlConnection.getJarFile();
                    // check if this is not a folder
                    // we can't rely on jarEntry.isDirectory() because of http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6233323
                    if (!jarEntry.isDirectory() && jarFile.getInputStream(jarEntry) != null) {
                        inputStream = urlConnection.getInputStream();
                    }
                }

                if ("file".equals(url.getProtocol())) {
                    final File file = new File(url.toURI());
                    if (file.exists() && file.isFile() && file.canRead())
                        inputStream = url.openConnection().getInputStream();
                }

//                System.out.println("filePath"+filePath);
//                inputStream = classLoader.getResourceAsStream(filePath);
//                URL url = classLoader.getResource(filePath);

//                System.out.println("inputStream="+inputStream);

//                File file = new File(classLoader.getResource(filePath).getFile());
//
//                System.out.println("file="+file);
//
//                System.out.println("exists="+file.exists());
//                System.out.println("isFile="+file.isFile());
//                System.out.println("canRead="+file.canRead());

//                if (file.exists() && file.isFile() && file.canRead()) {

//                    System.out.println("canRead="+file.isFile());

//                文件夹 java.io.ByteArrayInputStream
//                文件  java.io.BufferedInputStream

//                System.out.println("type=" + inputStream.getClass());

//                if (inputStream == null) inputStream = classLoader.getResourceAsStream(staticFileFolder + "/" + path);
                if (inputStream != null) {
                    resourceResponse.headers().set(HttpHeaderNames.TRANSFER_ENCODING, HttpHeaderValues.CHUNKED);
                    {
                        //这个要缓存住
                        RuntimeMXBean bean = ManagementFactory.getRuntimeMXBean();
                        long startTime = bean.getStartTime();
                        long expiresTime = startTime + 1000 * 24 * 60 * 60;

                        Date expiresDate = new Date();

//                        resourceResponse.headers().set(HttpHeaderNames.EXPIRES, HttpHeaderValues.CHUNKED);
//                        resourceResponse.headers().setObject(HttpHeaderNames.LAST_MODIFIED, new Date(startTime));
                    }
                    ctx.write(resourceResponse);
                    ctx.write(new ChunkedStream(inputStream), ctx.newProgressivePromise());

                    handled = true;
                }

//                }
            }

            if (!handled && externalStaticFileFolder != null) {
                File file = new File(externalStaticFileFolder + path);
                if (file.exists() && file.isFile() && file.canRead()) {
                    RandomAccessFile raf = new RandomAccessFile(file, "r");
                    long length = raf.length();
                    resourceResponse.headers().setLong(HttpHeaderNames.CONTENT_LENGTH, length);
                    {
                        //缓存和过期时间设置
                        long lastModifiedTime = file.lastModified();

                        resourceResponse.headers();

                    }
                    ctx.write(resourceResponse);
                    ctx.write(new DefaultFileRegion(raf.getChannel(), 0, length), ctx.newProgressivePromise());
                    handled = true;
                }
            }

            if (!handled) return false;

            ChannelFuture lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);

            if (!isKeepAlive(request)) lastContentFuture.addListener(ChannelFutureListener.CLOSE);

        } catch (Exception ignore) {
//            e.printStackTrace();
            return false;
        }
        return true;
    }


    public static void handleImg(ChannelHandlerContext ctx, HttpRequest request) {
        try {

            final String uri = request.uri();
            final QueryStringDecoder query = new QueryStringDecoder(uri);

            String path = query.path();

            String fileName = path.substring(path.lastIndexOf('/') + 1);

            String mimeType = MIMEs.mimeTypeByPath(path);

//            File file=new File("src/main/resources/favicon.ico");
//            RandomAccessFile raf = new RandomAccessFile(file, "r");
//            long fileLength = raf.length();
//
//            HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK);
//            response.headers().set(CONTENT_TYPE, mimeType);
//            if (isKeepAlive(request)) response.headers().set(CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
//            response.headers().set(CONTENT_LENGTH,fileLength);
//
//
//            // Write the initial line and the header.
//            ctx.write(response);
//
//            ChannelFuture   sendFileFuture =
//                    ctx.write(new DefaultFileRegion(raf.getChannel(), 0, fileLength), ctx.newProgressivePromise());
//            // Write the end marker.
//            ChannelFuture  lastContentFuture = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
//            if (!isKeepAlive(request)) lastContentFuture.addListener(ChannelFutureListener.CLOSE);
//
//            {
//                InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
//                byte[] bytes2 = ByteStreams.toByteArray(in);
//                System.out.println(bytes2.length);
//
//                byte[] bytes = IOUtils.toByteArray(in);
//
////                StringWriter writer = new StringWriter();
////                IOUtils.copy(in, writer, "UTF-8");
////
////                String theString = writer.toString();
////
////                int l=theString.length();
//                ByteBuf content = Unpooled.wrappedBuffer(bytes);
//
//                int l2=content.readableBytes();
//
////                System.out.println(l);
//                System.out.println(l2);
//
//            }
            {
                File file = new File("D:\\gitosc\\busuanzi\\target\\classes\\" + fileName);
                FileInputStream fs = new FileInputStream(file);
                System.out.println(fs.available());

                InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
                System.out.println(in.available());

//                ByteBuf content = Unpooled.wrappedBuffer(theString.getBytes(Charsets.UTF_8));
                HttpResponse response1 = new DefaultFullHttpResponse(HTTP_1_1, OK);
//            response.headers().set("Transfer-Encoding", "chunked");
                response1.headers().set(HttpHeaderNames.CONTENT_TYPE, mimeType);
//            response.headers().set(CONTENT_TYPE, "text/plain");
                if (isKeepAlive(request))
                    response1.headers().set(HttpHeaderNames.CONNECTION, HttpHeaderValues.KEEP_ALIVE);
                response1.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, in.available());

                ctx.write(response1);

                ChannelFuture writeFuture = ctx.write(new ChunkedStream(in), ctx.newProgressivePromise());

                ChannelFuture lastContentFuture1 = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
//
                if (!isKeepAlive(request)) lastContentFuture1.addListener(ChannelFutureListener.CLOSE);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    public static void main1(String[] args) {
//        System.out.println(System.getProperty("java.version"));
//
//        File f = new File(System.getProperty("java.home"), "lib");
//        f = new File(f, "mime.types");
//        System.out.println(f.exists() + " \t - " +f);
//
//        f = new File(System.getProperty("user.home"), ".mime.types");
//        System.out.println(f.exists() + " \t - " +f);

        MimetypesFileTypeMap mfm = new MimetypesFileTypeMap();
        System.out.println(mfm.getContentType("a.js"));
        System.out.println(mfm.getContentType("a.png"));
        System.out.println(mfm.getContentType("a.jpg"));
        System.out.println(mfm.getContentType("a.au"));
        System.out.println(mfm.getContentType("a.htm"));
    }

    public static void main(String[] args) {
        File f = new File("src/main/resources/favicon.ico");
        System.out.println(f.length());
        System.out.println(f.exists());


        MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
        mimeTypesMap.addMimeTypes("application/javascript js javascript");
        mimeTypesMap.addMimeTypes("image/x-icon ico");
        mimeTypesMap.addMimeTypes("text/css css");
        mimeTypesMap.addMimeTypes("image/png png");
        mimeTypesMap.addMimeTypes("image/bmp bmp");
        mimeTypesMap.addMimeTypes("text/xml xml");

        File file = new File("E:\\angularjs\\hello\\ttt.js");
        System.out.println(mimeTypesMap.getContentType("ttt.js"));
        System.out.println(mimeTypesMap.getContentType("sad/sf/dsf/dsf\\sdfsd\ttt.javascript"));
        System.out.println(mimeTypesMap.getContentType("ttt.jpg"));
        System.out.println(mimeTypesMap.getContentType("ttt.html"));
//        response.headers().set(CONTENT_TYPE, mimeTypesMap.getContentType(file.getPath()));
    }
}
